package com.example.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.example.common.Result;
import com.example.common.enums.ResultCodeEnum;
import com.example.common.enums.RoleEnum;
import com.example.entity.*;
import com.example.service.*;
import com.example.utils.TokenUtils;
import org.springframework.web.bind.annotation.*;
import sun.swing.BakedArrayList;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 基础前端接口
 */
@RestController
public class WebController {

    @Resource
    private AdminService adminService;
    @Resource
    private BusinessService businessService;
    @Resource
    private UserService userService;
    @Resource
    private DeliveryService deliveryService;
    @Resource
    private OrdersService ordersService;
    @Resource
    private OrdersItemService ordersItemService;
    @Resource
    private CategoryService categoryService;

    @GetMapping("/")
    public Result hello() {
        return Result.success("访问成功");
    }

    /**
     * 登录
     */
    @PostMapping("/login")
    public Result login(@RequestBody Account account) {
        if (ObjectUtil.isEmpty(account.getUsername()) || ObjectUtil.isEmpty(account.getPassword())
                || ObjectUtil.isEmpty(account.getRole())) {
            return Result.error(ResultCodeEnum.PARAM_LOST_ERROR);
        }
        if (RoleEnum.ADMIN.name().equals(account.getRole())) {
            account = adminService.login(account);
        } else if (RoleEnum.BUSINESS.name().equals(account.getRole())) {
            account = businessService.login(account);
        }else if (RoleEnum.USER.name().equals(account.getRole())) {
            account = userService.login(account);
        }else if (RoleEnum.DELIVERY.name().equals(account.getRole())) {
        account = deliveryService.login(account);
    }
        return Result.success(account);
    }

    /**
     * 注册
     */
    @PostMapping("/register")
    public Result register(@RequestBody Account account) {
        if (StrUtil.isBlank(account.getUsername()) || StrUtil.isBlank(account.getPassword())
                || ObjectUtil.isEmpty(account.getRole())) {
            return Result.error(ResultCodeEnum.PARAM_LOST_ERROR);
        }
        if (RoleEnum.BUSINESS.name().equals(account.getRole())) {
            businessService.register(account);
            return Result.success();
        }else if (RoleEnum.USER.name().equals(account.getRole())) {
            userService.register(account);
            return Result.success();
        }
        return Result.error(ResultCodeEnum.REGISTER_FALSE);
    }

    /**
     * 修改密码
     */
    @PutMapping("/updatePassword")
    public Result updatePassword(@RequestBody Account account) {
        Account currentUser = TokenUtils.getCurrentUser();
        account.setUsername(currentUser.getUsername());
        account.setRole(currentUser.getRole());
        if (StrUtil.isBlank(account.getUsername()) || StrUtil.isBlank(account.getPassword())
                || ObjectUtil.isEmpty(account.getNewPassword())) {
            return Result.error(ResultCodeEnum.PARAM_LOST_ERROR);
        }
        if (RoleEnum.ADMIN.name().equals(account.getRole())) {
            adminService.updatePassword(account);
        }else if (RoleEnum.BUSINESS.name().equals(account.getRole())) {
            businessService.updatePassword(account);
        }else if (RoleEnum.USER.name().equals(account.getRole())) {
            userService.updatePassword(account);
        }else if (RoleEnum.DELIVERY.name().equals(account.getRole())) {
            deliveryService.updatePassword(account);
        }
        return Result.success();
    }

    /**
     * 获取统计图数据
     * @return 动态数据
     */
    @GetMapping("/charts")
    public Result charts( Orders order) {

        // 包装折线图的数据
        order.setStatus("待评价");
        List<Orders> list = ordersService.selectAll(order);
        order.setStatus("已完成");
        List<Orders> list1 = ordersService.selectAll(order);
        list.addAll(list1);
        for (Orders o : list) {
            o.setTime(o.getTime().substring(0,11));
        }
        Set<String> dates = list.stream().map(Orders::getTime).collect(Collectors.toSet());
        List<String> dateList = CollUtil.newArrayList(dates);
        dateList.sort(Comparator.naturalOrder());
        List<Dict> lineList = new ArrayList<>();
        for (String date : dateList) {
            // 统计当前日期的所有金额总数和
            BigDecimal sum = list.stream().filter(orders -> orders.getTime().equals(date)).map(Orders::getActual)
                    .reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
            Dict dict = Dict.create();
            Dict line = dict.set("date", date).set("value", sum);
            lineList.add(line);
        }

        //前置处理：过滤掉已经取消的订单
        OrdersItem ordersItem = new OrdersItem();
        //在折线图已经处理过的list中获取orderId
        List<OrdersItem> ordersItemList = new ArrayList<>();
        for (Orders o : list) {
            ordersItem.setOrderId(o.getId());
            List<OrdersItem> ordersItemListPart = ordersItemService.selectAll(ordersItem);
            ordersItemList.addAll(ordersItemListPart);
        }
        // 柱状图数据
        List<Dict> barList = new ArrayList<>();
        Set<String> names = ordersItemList.stream().map(OrdersItem::getGoodsName).collect(Collectors.toSet());
        for (String name : names) {
            // 统计当前分类的所有金额总数和
            BigDecimal sum = ordersItemList.stream().filter(ordersItem1 -> ordersItem1.getGoodsName().equals(name)).map(OrdersItem::getAmount)
                    .reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
            Dict dict = Dict.create();
            Dict bar = dict.set("name", name).set("value", sum);
            barList.add(bar);
        }

        Category category = new Category();
        category.setBusinessId(order.getBusinessId());
        List<Category> categoryList = categoryService.selectAll(category);
        //饼图数据
        List<Dict> pieList = new ArrayList<>();
        Set<String> categories = categoryList.stream().map(Category::getName).collect(Collectors.toSet());
        for (String c : categories) {
            // 统计当前分类的所有金额总数和
            BigDecimal sum = ordersItemList.stream().filter(ordersItem1 -> ordersItem1.getCategoryName().equals(c)).map(OrdersItem::getAmount)
                    .reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
            Dict dict = Dict.create();
            Dict pie = dict.set("name", c).set("value", sum);
            pieList.add(pie);
        }
        // 包装所有数据
        Dict res = Dict.create().set("line", lineList).set("bar", barList).set("pie",pieList);
        return Result.success(res);
    }

    //获取销售总额的排名
    @GetMapping("/data")
    public Result getData(){
        Orders order = new Orders();
        order.setStatus("待评价");
        List<Orders> list = ordersService.selectAll(order);
        order.setStatus("已完成");
        List<Orders> list1 = ordersService.selectAll(order);
        list.addAll(list1);
        Business business = new Business();
        List<Business> businessList = businessService.selectAll(business);
//        List<Business> businessListSort  = new ArrayList<>();
        for (Business b : businessList) {
            //filter过滤器，过滤出与b的business_id值相同的元素，map对应到每一个元素。redeuce是聚合函数，使用Bigdeciaml类中的add函数实现累加
            BigDecimal sum = list.stream().filter(orders -> orders.getBusinessId().equals(b.getId())).map(Orders::getActual)
                    .reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
            b.setTotal(sum);
        }
        quickSort(businessList,0,businessList.size()-1);
        Collections.reverse(businessList);
//        if(businessList.size() >= 5)
//            businessList.subList(0,5);
        return Result.success(businessList);
    }

    //快速排序算法
    public void quickSort(List<Business> b, int start, int end) {
        //数组有多个元素进行排序
        if (start < end) {
            Business base = b.get(start);//以要进行排序数组第0个元素为base
            int left = start;//左指针
            int right = end;//右指针
            while (left < right) {
                //从右向左找，比base大，right--
                while (left< right && b.get(right).getTotal().compareTo(base.getTotal()) > -1) {
                    right--;
                }
                //比base小，替换left所在位置的数字
                b.set(left,b.get(right));
                //从左向右找，比base小，left++
                while (left < right &&b.get(left).getTotal().compareTo(base.getTotal()) < 1){
                    left++;
                }
                //比base大，替换right所在位置的数字
                b.set(right,b.get(left));
            }
            b.set(left,base);//此时left=right，用base替换这个位置的数字
            //排列比base小的数字的数组
            quickSort(b, start, left - 1);
            //排列比base大的数字的数组
            quickSort(b, left + 1, end);
        }
    }

}
